package com.nidu.demo.online.executor.query;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageResponse;
import com.nidu.demo.log.model.LoginLogCriteria;
import com.nidu.demo.log.gateway.LoginLogGateway;
import com.nidu.demo.log.model.LoginLog;

import com.nidu.demo.oauth2.ability.OAuth2AccessTokenDomainService;
import com.nidu.demo.oauth2.gateway.OAuth2AccessTokenGateway;
import com.nidu.demo.oauth2.model.OAuth2AccessToken;
import com.nidu.demo.oauth2.model.OAuth2AccessTokenCriteria;
import com.nidu.demo.online.dto.OnlineUserDetailCO;
import com.nidu.demo.online.dto.OnlineUserPageQry;
import com.nidu.demo.user.gateway.UserGateway;
import com.nidu.demo.user.model.User;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 站内信消息分页查询执行器
 *
 * @author auto
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OnlineUserPageQryExe {

    private final OAuth2AccessTokenGateway accessTokenGateway;
    private final UserGateway userGateway;
    private final LoginLogGateway loginLogGateway;

    public PageResponse<OnlineUserDetailCO> pageOnlineUsers(OnlineUserPageQry qry) {
        List<OnlineUserDetailCO> allOnlineUsers = getOnlineUserDetails();

        // 根据查询条件过滤
        List<OnlineUserDetailCO> filteredUsers = allOnlineUsers.stream()
                .filter(user -> {
                    if (qry.getUserId() != null && !qry.getUserId().equals(user.getUserId())) {
                        return false;
                    }
                    if (qry.getUserType() != null && !qry.getUserType().equals(user.getUserType())) {
                        return false;
                    }
                    if (StrUtil.isNotBlank(qry.getUsername()) && !user.getUsername().contains(qry.getUsername())) {
                        return false;
                    }
                    if (StrUtil.isNotBlank(qry.getUserIp()) && !user.getUserIp().contains(qry.getUserIp())) {
                        return false;
                    }
                    return true;
                })
                .collect(Collectors.toList());

        // 手动分页
        int pageIndex = qry.getPageIndex();
        int pageSize = qry.getPageSize();
        int total = filteredUsers.size();
        int fromIndex = (pageIndex - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);

        List<OnlineUserDetailCO> pageData = fromIndex < total ?
                filteredUsers.subList(fromIndex, toIndex) : new ArrayList<>();

        return PageResponse.of(pageData, total, pageSize, pageIndex);
    }

    public List<OnlineUserDetailCO> getOnlineUserDetails() {
        List<OnlineUserDetailCO> onlineUsers = new ArrayList<>();
        Map<Long, List<OAuth2AccessToken>> userTokenMap = accessTokenGateway.getAllValidTokens();

        for (Map.Entry<Long, List<OAuth2AccessToken>> entry : userTokenMap.entrySet()) {
            Long userId = entry.getKey();
            List<OAuth2AccessToken> userTokens = entry.getValue();

            // 获取最新的令牌作为主要信息来源
            OAuth2AccessToken latestToken = userTokens.stream()
                    .max(Comparator.comparing(OAuth2AccessToken::getCreateTime))
                    .orElse(null);

            if (latestToken != null) {
                OnlineUserDetailCO onlineUser = buildOnlineUserDetail(userId, latestToken);
                if (onlineUser != null) {
                    onlineUsers.add(onlineUser);
                }
            }
        }

        // 按最后活跃时间倒序排列
        onlineUsers.sort((a, b) -> b.getLastActiveTime().compareTo(a.getLastActiveTime()));

        return onlineUsers;
    }

    /**
     * 构建在线用户详情
     */
    private OnlineUserDetailCO buildOnlineUserDetail(Long userId, OAuth2AccessToken token) {
        try {
            // 获取用户信息
            User user = userGateway.getById(userId);
            if (user == null) {
                return null;
            }

            OnlineUserDetailCO detail = new OnlineUserDetailCO();
            detail.setUserId(userId);
            detail.setUsername(user.getUsername());
            detail.setLoginTime(user.getLoginTime());
            detail.setLastActiveTime(user.getLoginTime());

            // 获取最近的登录成功日志
            LoginLog latestLogin = loginLogGateway.getLastLoginSuccessLog(user.getId());

            if (latestLogin != null) {
                detail.setUserType(latestLogin.getUserType());
                detail.setUserIp(latestLogin.getUserIp());
                detail.setUserAgent(latestLogin.getUserAgent());
                detail.setLoginType(latestLogin.getLoginType());
            }

            // 设置会话ID（使用访问令牌的部分内容）
            if (StrUtil.isNotBlank(token.getAccessToken())) {
                detail.setSessionId(token.getAccessToken());
            }

            // 计算在线时长
            detail.setOnlineDuration(Duration.between(user.getLoginTime(), LocalDateTime.now()).toMinutes());

            return detail;
        } catch (Exception e) {
            log.error("构建用户 {} 在线详情失败", userId, e);
            return null;
        }
    }

}
